/*
 * File:   driver_timer.c
 * Author: Ich
 *
 * Created on 23.02.2014, 16:03
 *
 */

#include <plib.h>
#include "driver_timer.h"
#include "driver_led.h"
#include "api_clk.h"
/*******************************************************************************
 *  private preprocessing definitions
 */

 /*******************************************************************************
 *  private variables
 */

/*******************************************************************************
 *  private functions
 */

 /*******************************************************************************
 *  public variables (defined by external)
 */


/*******************************************************************************
 *  public functions
 */

/* timer #1 on. Used for counting 1ms steps */
void drvTmr1_on(void)
{
    // (PBCLK / T2_PS_1_1 / DRVLED_FREQ )
    // = 38.4 MHz / 1 / 1'000 = 38'400
    static const UINT16 tmr1period = (apiClk_getPeripheralClock() / 1000);

    // Configure Timer 1 using PBCLK as input, 1:256 prescaler
    // Period matches the Timer 1 frequency, so the interrupt handler
    // will trigger every "tmr1period"
    OpenTimer1(T1_ON | T2_PS_1_1, tmr1period);
}

/* gets the actual value of timer #1. 1 step is 1ms*/
UINT16 drvTmr1_getValue(void)
{
    return ReadTimer1();
}



/* timer #2 on. Used for Leds. Generates an interrupt every 1.25usec */
void drvTmr2_on(void)
{
    // (PBCLK / T2_PS_1_1 / DRVLED_FREQ )
    // = 38.4 MHz / 1 / 800'000 = 48
    static const UINT16 tmr2period = (apiClk_getPeripheralClock() / DRVLED_FREQ);

    // Configure Timer 4 using PBCLK as input, 1:256 prescaler
    // Period matches the Timer 4 frequency, so the interrupt handler
    // will trigger every "tmr4period"
    OpenTimer2(T2_ON | T2_PS_1_1, tmr2period);
}

/* timer #2 off */
void drvTmr2_off(void)
{
    CloseTimer2();
}

/* timer #2 reset (off, then on) */
void drvTmr2_reset(void)
{
    drvTmr2_off();
    drvTmr2_on();
}


/* returns the timer #2 end register.
 * --> timer counts from 0 to "ReadPeriod2" */
UINT16 drvTmr2_getCntTarget()
{
    return ReadPeriod2();
}



/* timer #3 on. Used for Buzzer. Generates an interrupt every "freq" [Hz] */
void drvTmr3_on(UINT16 freq)
{
    // Configure Timer 3 using PBCLK as input, 1:32 prescaler
    // Period matches the Timer 3 frequency, so the interrupt handler
    // will trigger every "tmr3period"
    OpenTimer3(T3_ON | T3_PS_1_32, 10000);
    drvTmr3_setCntTarget(freq);
}

/* timer #3 off */
void drvTmr3_off(void)
{
    CloseTimer3();
}


/* returns the timer #3 end register.
 * --> timer counts from 0 to "ReadPeriod3" */
UINT16 drvTmr3_getCntTarget()
{
    return ReadPeriod3();
}


/* Sets the timer #3 end register.
 * --> timer counts from 0 to "WritePeriod3" */
void drvTmr3_setCntTarget (UINT16 freq)
{
    if(freq > 0)
    {
        // (PBCLK / T3_PS_1_32 / freq = 38.4 MHz / 32 / freq )
        WritePeriod3(apiClk_getPeripheralClock() / 32 / freq);
    }
    else
    {
        WritePeriod3(0);
    }
}



/* timer #4 on. Used for Buzzer. Generates an interrupt every 200 msec */
void drvTmr4_on(void)
{
    // (PBCLK / T4_PS_1_256 / freq = 38.4 MHz / 256 / freq )
    // = 38.4 MHz / 256 / 5 = 200 msec = 30'000
    static const UINT16 tmr4period = (apiClk_getPeripheralClock() / 256 / 5);

    // Configure Timer 4 using PBCLK as input, 1:256 prescaler
    // Period matches the Timer 4 frequency, so the interrupt handler
    // will trigger every "tmr4period"
    OpenTimer4(T4_ON | T4_PS_1_256, tmr4period);
}

/* timer #4 off */
void drvTmr4_off(void)
{
    CloseTimer4();
}

/* timer #4 reset (off, then on) */
void drvTmr4_reset(void)
{
    drvTmr4_off();
    drvTmr4_on();
}

